﻿using System;
using System.Text;
using System.Threading;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace Consumer
{
    class Consumer
    {
        static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    //声明交换器
                    //channel.ExchangeDeclare("logs","fanout");
                    //channel.ExchangeDeclare("direct_logs", ExchangeType.Direct);
                    channel.ExchangeDeclare("topic_logs", ExchangeType.Topic);

                    //如果不向QueueDeclare()方法提供任何参数，实际上就是创建了一个非持久化、独占、且自动删除的随机命名队列
                    var queueName = channel.QueueDeclare().QueueName;

                    if (args.Length < 1)
                    {
                        //Console.Error.WriteLine("Usage: {0} [info] [warning] [error]", Environment.GetCommandLineArgs()[0]);
                        Console.Error.WriteLine("Usage: {0} [binding_key]", Environment.GetCommandLineArgs()[0]);
                        Console.WriteLine("Press [enter] to exit");
                        Console.ReadLine();
                        Environment.ExitCode = 1;
                        return;
                    }

                    foreach (var severity in args)
                    {
                        //绑定队列到指定的交换器上
                        //channel.QueueBind(queueName, "direct_logs", severity);
                        channel.QueueBind(queueName, "topic_logs", severity);
                    }



                    Console.WriteLine("[*] Waiting for message");

                    //构建消费者实例
                    var consumer = new EventingBasicConsumer(channel);
                    //绑定消息接收事件
                    consumer.Received += (model, ea) =>
                    {
                        var body = ea.Body.Span;
                        var message = Encoding.UTF8.GetString(body);
                        var routingKey = ea.RoutingKey;
                        Console.WriteLine("[x] Received {0} : '{1}'", message,routingKey);

                        //模拟耗时操作
                        //int dots = message.Split('.').Length - 1;
                        //Thread.Sleep(dots * 1000);

                        //Console.WriteLine("[x] Done");

                        //手动发送消息确认信号
                        //channel.BasicAck(ea.DeliveryTag, false);
                    };
                    // autoAck:false - 关闭自动消息确认，调用BasicAck方法进行手动消息确认
                    // autoAck:true - 开启自动消息确认，当消费者接收到消息后就自动发送Ack信号，无论消息是否正确处理完毕。
                    channel.BasicConsume(queueName, true, consumer);
                    Console.WriteLine("Press [enter] to exit.");
                    Console.ReadLine();
                }
            }
        }
    }
}